use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone)]
pub struct Config {
    #[serde(default = "Server::default")]
    pub server: Server,
    #[serde(default = "Config::default_eps")]
    pub entry_points: Vec<EntryPoint>,
    #[serde(default = "IngressLister::default")]
    pub ingress: IngressLister,
    #[serde(default = "ServicesLister::default")]
    pub services: ServicesLister,
}
impl Config {
    pub fn default_eps() -> Vec<EntryPoint> {
        vec![EntryPoint::new()]
    }
}
#[derive(Serialize, Deserialize, Clone, Default)]
pub struct Server {
    #[serde(default = "bool::default")]
    pub release: bool,
    #[serde(default = "LogLevel::default")]
    pub log_level: LogLevel,
}
impl Config {
    #[allow(unused_imports)]
    pub fn json_show(&self) -> String {
        serde_json::to_string(self)
            .unwrap_or_else(|err| format!("config json marshal error:{}", err.to_string()))
    }
}
#[derive(Serialize, Deserialize, Clone)]
pub enum LogLevel {
    Panic,
    Error,
    Warn,
    Info,
    Debug,
}
impl Default for LogLevel {
    fn default() -> Self {
        LogLevel::Debug
    }
}
#[derive(Serialize, Deserialize, Clone, Default)]
pub struct EntryPoint {
    pub name: String,
    #[serde(default = "EntryPoint::default_addr")]
    pub addr: String,
    #[serde(rename = "type", default = "EPType::default")]
    pub ty: EPType,
    pub ca_file: Option<String>,
    pub private_key: Option<String>,
    pub publish_key: Option<String>,
}
impl EntryPoint {
    pub(crate) fn new() -> Self {
        Self {
            name: String::from("default"),
            addr: Self::default_addr(),
            ..Self::default()
        }
    }
}
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub enum EPType {
    Http,
    Grpc,
    Tcp,
    WebSocket,
}
impl Default for EPType {
    fn default() -> Self {
        EPType::Http
    }
}
impl EntryPoint {
    fn default_addr() -> String {
        String::from("0.0.0.0:80")
    }
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct IngressLister {
    #[serde(default = "IngressLister::default_enable")]
    pub enable: bool,
    #[serde(default = "IngressLister::default_selector")]
    pub selector: String,
    // #[serde(default="IngressLister::default_namespaces")]
    pub namespaces: Option<String>,
}
impl IngressLister {
    pub fn default() -> Self {
        Self {
            enable: Self::default_enable(),
            selector: Self::default_selector(),
            namespaces: None,
        }
    }
    fn default_enable() -> bool {
        true
    }
    fn default_selector() -> String {
        String::from("ingress-controller-app=rust-ingress")
    }
    // fn default_namespaces()->String{String::from("default")}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ServicesLister {
    #[serde(default = "ServicesLister::default_enable")]
    pub enable: bool,
    #[serde(default = "ServicesLister::default_selector")]
    pub selector: String,
    // #[serde(default="ServicesLister::default_namespaces")]
    pub namespaces: Option<String>,
}
impl ServicesLister {
    pub fn default() -> Self {
        Self {
            enable: Self::default_enable(),
            selector: Self::default_selector(),
            namespaces: None,
        }
    }
    fn default_enable() -> bool {
        true
    }
    fn default_selector() -> String {
        String::from("app=rust-ingress")
    }
    // fn default_namespaces()->String{String::from("default")}
    // fn default_ep_selector()->String{String::from("end_point_name")}
}
